package com.runvp.netty.runnables;

import com.alibaba.fastjson.JSONObject;
import com.runvp.common.config.RunvpConfig;
import com.runvp.common.constant.ConstantRedisKey;
import com.runvp.common.enums.LineStatus;
import com.runvp.common.enums.NettyCmd;
import com.runvp.common.enums.NettyType;
import com.runvp.common.model.tcp.MessageReceiveBody;
import com.runvp.common.model.tcp.MessageResBody;
import com.runvp.common.util.ToolUtils;
import com.runvp.common.util.enc.aes128gcm.Aes128GcmUtils;
import com.runvp.common.utils.DateUtils;
import com.runvp.netty.build.BuildHttpClint;
import com.runvp.netty.constant.NettyConstant;
import com.runvp.service.biz.domain.BizDevice;
import com.runvp.service.build.BuildQRCode;
import com.runvp.service.tcp.TcpService;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class XLRunnable implements Runnable {

    private Channel channel;

    private TcpService tcpService;

    private MessageReceiveBody parseBody;

    public XLRunnable(Channel channel, TcpService tcpService, MessageReceiveBody parseBody) {
        this.channel = channel;
        this.tcpService = tcpService;
        this.parseBody = parseBody;
    }

    @Override
    public void run() {
//        xl(channel);
    }

    /**
     * 设备发送心跳包
     */
    public MessageResBody handles() {
        String channelId = NettyConstant.getChannelId(channel);
        log.info("心跳处理channelId: {}",channelId);
        String sn = NettyConstant.allOnlineChannleIds.get(channelId);
        log.info("心跳处理sn: {}",sn);
        parseBody.setTerminalId(sn);
        return BuildHttpClint.postJson("/app/cmd/xl",parseBody);
    }
    /**
     * 设备发送心跳包
     */
    public long xl(Channel channel) {
        long st = System.currentTimeMillis();
        long ast = st;
        String sn = "";
        try{
            String batchNo = System.nanoTime()+"";
            sn = NettyConstant.allOnlineChannleIds.get(NettyConstant.getChannelId(channel));
            long id = ToolUtils.objTOLong(tcpService.instanceRedisUtil().getCacheObject(ConstantRedisKey.DEVICE_SN_ID+sn));
            parseBody.setTerminalId(sn);
            String json = JSONObject.toJSONString(parseBody);
            log.info("设备发送心跳包报文实体 ：{}", json);
            tcpService.addBizTcpRecord(parseBody.setBatchNo(batchNo));
            handleBizDevice(parseBody);
            MessageResBody resBody = buildRes(id);
            resBody.setTerminalId(sn);
            tcpService.addBizTcpRecord(resBody.setBatchNo(batchNo));
            return id;
        }catch (Exception e){
            log.error("本次设备心跳【{}】处理异常共耗时:【{} ms】,error:{}",sn,(System.currentTimeMillis()-ast),e.getMessage());
        }finally {
            log.info("本次设备心跳【{}】线程池内解析处理共耗时:【{} ms】",sn,(System.currentTimeMillis()-ast));
        }
        return 0;
    }

    /**
     * 处理设备
     *
     * @return str
     */
    private void handleBizDevice(MessageReceiveBody parseBody) {
        String sn = parseBody.getTerminalId();
        BizDevice query = new BizDevice();
        query.setDeviceCode(sn);
        List<BizDevice> deviceList = tcpService.instanceIBizDeviceService().selectBizDeviceList(query);
        BizDevice device;
        if (CollectionUtils.isEmpty(deviceList)) {
            log.error("设备【{}】未安装",sn);
            return;
        } else {
            device = deviceList.get(0);
        }
        device.setLastUpdateTime(DateUtils.getNowDate());
        device.setLineStatus(LineStatus.ON_LINE.getCode());
        device.setQrCode(BuildQRCode.createCode(device.getDeviceCode(), RunvpConfig.getPreview() + "/wechat.html?baseSn=" + device.getDeviceCode()));
        tcpService.instanceIBizDeviceService().updateBizDevice(device);
        log.info("设备【{}】执行修改,执行时间:【{}】", sn, DateUtils.now());
    }

    /**
     * 结构结果体
     * @return str
     */
    private String buildBodys(long id){
        Map<String,Object> map = new HashMap<>();
        map.put("id",id);
        StringBuilder sb = new StringBuilder(Aes128GcmUtils.getInstance().encrypt(JSONObject.toJSONString(map)));
        return sb.toString().toUpperCase();
    }

    /**
     * 默认报文
     *
     * @return MessageResBody
     */
    public MessageResBody defaultRes() {
        long id = xl(channel);
        return buildRes(id);
    }
    /**
     * 默认报文
     *
     * @return MessageResBody
     */
    public MessageResBody buildRes(long id) {
        MessageResBody resBody = new MessageResBody(NettyType.SERVER_RECEIVE_DEVICE.getCode(), NettyCmd.XL.getCode());
        resBody.setDid("000000000000");
        resBody.setVersion("01");
        resBody.setBody(buildBodys(id)).buildRes();
        return resBody;
    }
}
